package com.Lubaichen.Wiki.controller;

import com.Lubaichen.Wiki.req.UserLoginReq;
import com.Lubaichen.Wiki.req.UserQueryReq;
import com.Lubaichen.Wiki.req.UserResetPasswordReq;
import com.Lubaichen.Wiki.req.UserSaveReq;
import com.Lubaichen.Wiki.resp.CommonResp;
import com.Lubaichen.Wiki.resp.UserLoginResp;
import com.Lubaichen.Wiki.resp.UserQueryResp;
import com.Lubaichen.Wiki.resp.PageResp;
import com.Lubaichen.Wiki.service.UserService;
import com.Lubaichen.Wiki.utils.SnowFlake;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import javax.validation.Valid;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * @author Lubaichen
 * @date 2022年02月27日 21:24
 */
@RestController
// @Controller : 返回的是页面，前后端分离基本用不到这个注解。
// @ResponseBody : 用来返回字符串或JSON对象，更多的是返回JSON对象。
@RequestMapping("/user")
public class UserController {
    private static final Logger LOG = LoggerFactory.getLogger(ControllerExceptionHandler.class);
    @Autowired
    private UserService userService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private SnowFlake snowFlake;

    @GetMapping("/list") //Spring会自动将参数映射到类属性
    public CommonResp UserList(@Valid UserQueryReq req) {
        CommonResp<PageResp<UserQueryResp>> resp = new CommonResp<>();
        PageResp<UserQueryResp> list = userService.list(req);
        resp.setContent(list);
        return resp;
    }

    @PostMapping("/save")
    public CommonResp UserSave(@Valid @RequestBody UserSaveReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes(StandardCharsets.UTF_8)));
        CommonResp resp = new CommonResp<>();
        userService.save(req);
        return resp;
    }

    @DeleteMapping("/delete/{id}")
    public CommonResp deleteUserById(@PathVariable Long id) {
        CommonResp resp = new CommonResp<>();
        userService.deleteUserById(id);
        return resp;
    }

    @PostMapping("/reset-password")
    public CommonResp resetPassword(@Valid  @RequestBody UserResetPasswordReq req) {
        CommonResp commonResp = new CommonResp<>();
        userService.resetPassword(req);
        return commonResp;
    }

    @PostMapping("/login")
    public CommonResp login(@Valid @RequestBody UserLoginReq req) {
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes(StandardCharsets.UTF_8)));
        CommonResp<UserLoginResp> commonResp = new CommonResp<>();
        UserLoginResp userLoginResp = userService.login(req);
        // 生成单点登录token，并加入redis中
        long token = snowFlake.nextId();
        userLoginResp.setToken(String.valueOf(token));
        LOG.info("生成单点登录token{}，并加入redis中", token);
        LOG.info("登录名:{}, 用户名:{}", userLoginResp.getLoginName(), userLoginResp.getName());
        // 将类对象放入redis中，这个类要实现Serializable接口
        commonResp.setContent(userLoginResp);
        redisTemplate.opsForValue().set(String.valueOf(token), JSONObject.toJSONString(userLoginResp), 3600 * 24, TimeUnit.SECONDS);
        return commonResp;
    }


    @GetMapping("/logout/{token}")
    public CommonResp logout(@PathVariable String token) {
        redisTemplate.delete(token);
        LOG.info("从redis中删除token");
        return new CommonResp<>();
    }
}
